﻿
using XiangziProjectTemplete.Core.IServices;
using XiangziProjectTemplete.Core.Model.Models;
using XiangziProjectTemplete.Core.Services.BASE;
using XiangziProjectTemplete.Core.IRepository.Base;
using XiangziProjectTemplete.Core.Model.PostParamModels.XiangziProjectTemplete;
using XiangziProjectTemplete.Core.Common.HttpContextUser;
using System;
using XiangziProjectTemplete.Core.Common.Helper;
using XiangziProjectTemplete.Core.Model.Enums.XiangziProjectTemplete;
using XiangziProjectTemplete.Core.IRepository.UnitOfWork;
using System.Threading.Tasks;
using iWareModels;
using System.Collections.Generic;
using System.Linq;
using XiangziProjectTemplete.Core.Model;

namespace XiangziProjectTemplete.Core.Services
{
    /// <summary> 
    /// Agv任务服务接口实现 
    /// </summary>	 
    public class Les_AgvTaskServices : BaseServices<Les_AgvTask>, ILes_AgvTaskServices
    {
        private readonly IBaseRepository<Les_AgvTask> _dal;
        private readonly IBaseRepository<Base_Station> _staion_dal;
        private readonly IBaseRepository<Les_AgvTaskPhase> _dal_AgvTaskPhase;
        public Les_AgvTaskServices(
            IBaseRepository<Les_AgvTaskPhase> dal_AgvTaskPhase,
            IBaseRepository<Les_AgvTask> dal, IBaseRepository<Base_Station> staion_dal)
        {
            this._dal_AgvTaskPhase = dal_AgvTaskPhase;
            this._dal = dal;
            base.BaseDal = dal;
            this._staion_dal = staion_dal;
        }


        /// <summary>
        /// 创建 分拣出库的任务
        /// </summary>
        /// <param name="param"></param>
        /// <param name="_user"></param>
        /// <param name="_unitOfWork"></param>
        /// <returns></returns>
        public async Task<bool> CreateSortOutStoreTask(LES_SortOutStoreTaskPostParam param, IUser _user, IUnitOfWork _unitOfWork)
        {
            var taskNo = BusinessHelper.CreatePlcTaskId();//生成任务号
            Les_AgvTask agvTask = new Les_AgvTask()
            {
                MaterialName = param.MaterialName,
                MaterialCode = param.MaterialCode,
                SalverCode = param.SalverCode,
                SourcePlace = param.SourcePlace,
                SourcePlaceName = param.SourcePlaceName,
                ToPlace = param.ToPlace,
                ToPlaceName = param.ToPlaceName,
                CreateBy = _user.Name,
                CreateId = _user.ID,
                ModifyId = _user.ID,
                ModifyBy = _user.Name,
                ModifyTime = DateTime.Now,
                CreateTime = DateTime.Now,
                OperationRemark = "新建任务",
                TaskCreateTime = DateTime.Now,
                TaskNo = taskNo,
                TaskStatus = Convert.ToInt32(TaskStatusEnum.未开始),
                CallOrderNo = "",//叫料单号暂时未写！！！！
                TaskType = Convert.ToInt32(AGVTaskType.缺料呼叫)
            };

            //事务处理
            try
            {
                _unitOfWork.BeginTran();

                await _dal.Add(agvTask);
                //锁定工位
                Base_Station sourcePlace = await _staion_dal.QueryById(param.SourcePlace);
                sourcePlace.IsLock = 1;
                sourcePlace.OperationRemark = "创建分拣出库任务时锁定来源库位";
                sourcePlace.ModifyTime = DateTime.Now;
                sourcePlace.ModifyBy = _user.Name;
                sourcePlace.ModifyId = _user.ID;
                await _staion_dal.Update(sourcePlace);

                Base_Station toPlace = await _staion_dal.QueryById(param.ToPlace);
                toPlace.IsLock = 1;
                toPlace.OperationRemark = "创建分拣出库任务时锁定目标库位";
                toPlace.ModifyTime = DateTime.Now;
                toPlace.ModifyBy = _user.Name;
                toPlace.ModifyId = _user.ID;
                await _staion_dal.Update(toPlace);


                _unitOfWork.CommitTran();

                return true;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackTran();
                throw;
            }
        }

        /// <summary>
        /// 创建 回库搬运的任务
        /// </summary>
        /// <param name="param"></param>
        /// <param name="_user"></param>
        /// <param name="_unitOfWork"></param>
        /// <returns></returns>
        public async Task<bool> CreateaBackStoreTask(LES_SortOutStoreTaskPostParam param, IUser _user, IUnitOfWork _unitOfWork)
        {
            var taskNo = BusinessHelper.CreatePlcTaskId();//生成任务号
            Les_AgvTask agvTask = new Les_AgvTask()
            {
                MaterialName = param.MaterialName,
                MaterialCode = param.MaterialCode,
                SalverCode = param.SalverCode,
                SourcePlace = param.SourcePlace,
                SourcePlaceName = param.SourcePlaceName,
                ToPlace = param.ToPlace,
                ToPlaceName = param.ToPlaceName,
                CreateBy = _user.Name,
                CreateId = _user.ID,
                ModifyId = _user.ID,
                ModifyBy = _user.Name,
                ModifyTime = DateTime.Now,
                CreateTime = DateTime.Now,
                OperationRemark = "新建任务",
                TaskCreateTime = DateTime.Now,
                TaskNo = taskNo,
                TaskStatus = Convert.ToInt32(TaskStatusEnum.未开始),
                CallOrderNo = "",//叫料单号暂时未写！！！！
                TaskType = Convert.ToInt32(AGVTaskType.余料回库搬运)
            };

            //事务处理
            try
            {
                _unitOfWork.BeginTran();

                await _dal.Add(agvTask);
                //锁定工位
                Base_Station sourcePlace = await _staion_dal.QueryById(param.SourcePlace);
                sourcePlace.IsLock = 1;
                sourcePlace.OperationRemark = "创建回库搬运任务时锁定来源库位";
                sourcePlace.ModifyTime = DateTime.Now;
                sourcePlace.ModifyBy = _user.Name;
                sourcePlace.ModifyId = _user.ID;
                await _staion_dal.Update(sourcePlace);

                Base_Station toPlace = await _staion_dal.QueryById(param.ToPlace);
                toPlace.IsLock = 1;
                toPlace.OperationRemark = "创建回库搬运任务时锁定目标库位";
                toPlace.ModifyTime = DateTime.Now;
                toPlace.ModifyBy = _user.Name;
                toPlace.ModifyId = _user.ID;
                await _staion_dal.Update(toPlace);


                _unitOfWork.CommitTran();

                return true;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackTran();
                throw;
            }
        }

        /// <summary>
        /// 根据任务号查询AGV任务
        /// </summary>
        /// <param name="taskNo"></param>
        /// <returns></returns>
        public async Task<Les_AgvTask> GetAgvTaskByTaskNo(string taskNo)
        {
            try
            {
                var agvTaskList = await _dal.Query(x => x.TaskNo == taskNo);
                if (agvTaskList == null || agvTaskList.Count == 0)
                    return null;
                if (agvTaskList.Count > 1)
                {
                    throw new Exception("找到任务号" + taskNo + "共" + agvTaskList.Count + "条记录！");
                }
                return agvTaskList[0];
            }
            catch (Exception)
            {
                throw;
            }
        }


        /// <summary>
        /// 根据 AGV任务ID 查找 该任务的详细阶段列表
        /// </summary>
        /// <param name="agvTaskId">AGV任务ID</param>
        /// <returns></returns>
        public async Task<List<Les_AgvTaskPhase>> GetAgvTaskPhaseList(string agvTaskId)
        {
            var reusltList = await _dal_AgvTaskPhase.Query(x => x.AgvTaskId == agvTaskId);
            if (reusltList != null && reusltList.Count > 0)
            {
                reusltList = reusltList.OrderBy(x => x.CreateTime).ToList();
            }
            return reusltList;
        }

        /// <summary>
        /// 根据 AGV任务号 查找 该任务的详细阶段列表
        /// </summary>
        /// <param name="agvTaskId">AGV任务ID</param>
        /// <returns></returns>
        public async Task<List<Les_AgvTaskPhase>> GetAgvTaskPhaseListByTaskNo(string agvTaskNo)
        {
            var reusltList = await _dal_AgvTaskPhase.Query(x => x.TaskNo == agvTaskNo);
            if (reusltList != null && reusltList.Count > 0)
            {
                reusltList = reusltList.OrderBy(x => x.CreateTime).ToList();
            }
            return reusltList;
        }


        /// <summary>
        /// 验证站点是否被AGV任务占用
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public async Task<MessageModel<bool>> ValidateIsUsingAgvTaskForStation(Base_Station station)
        {
            var agvTaskList = await _dal.Query(x => (x.SourcePlace == station.Id || x.ToPlace == station.Id)
              && x.TaskStatus != Convert.ToInt32(TaskStatusEnum.已完成)
              && x.TaskStatus != Convert.ToInt32(TaskStatusEnum.已取消)
             );
            if (agvTaskList != null && agvTaskList.Count > 0)
            {
                return MessageModel<bool>.Fail("站点[" + station.StationCode + "]已经被AGV任务'" + agvTaskList[0].TaskNo + "'占用！");
            }
            return MessageModel<bool>.Success("没有AGV任务占用");
        }
    }
}
